import 'dart:convert';

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:hitutor/UI/Account/Login.dart';
import 'package:hitutor/Util/MyColor.dart';
import 'package:hitutor/Widget/MyDialog.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'Global.dart';

class HttpGo {
  static final String GET = "get";
  static final String POST = "post";

  static final int DEMO = 1;
  static final int PRO = 2;

  static final int apiType = PRO; //

  static String DO_MAIN = apiType == DEMO ? "https://demo-hitutorapp.hitutor.com.tw" : "https://studentapp-api.hi-tr.com";
  static String ForgetUrl = apiType == DEMO
      ? "https://demologin.hitutor.com.tw/en/Login/RetrievePasswordPage"
      : "https://login.hi-tr.com/en/Login/RetrievePasswordPage";

  static Dio dio = Dio();
  static BuildContext? _context;

  static String getRealUrl(String url) {
    if (!url.startsWith("http")) {
      url = HttpGo.DO_MAIN + url;
    }
    return url;
  }

  // String testToken = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
  //     ".eyJzdWIiOiJ0ZXN0MDMxNzA0QGdtYWlsLmNtIiwibmFtZWlkIjoiMTY5MzQzIiwidHlwIjoiUyIsImVtYWlsIjoidGVzdDAzMTcwNEBnbWFpbC5jbSIsIm5iZiI6MTY0Nzc5MDA2OCwiZXhwIjoxNjc5MzI2MDY4LCJpYXQiOjE2NDc3OTAwNjgsImlzcyI6IkhpVHV0b3IifQ.Elro8CGiJtf8isxn2hRutNWE5SF9OgRbUvCmIhk4giY";

  HttpGo(BuildContext context, {int receiveTime = 30000, bool json = true, bool autoDomain = true}) {
    _context = context;
    dio.options.headers = {"Authorization": Global.token, "Content-Type": json ? "application/json" : "multipart/form-data"};
    dio.options.baseUrl = autoDomain ? DO_MAIN : "";
    dio.options.connectTimeout = receiveTime;
    dio.options.receiveTimeout = receiveTime;
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
      client.badCertificateCallback = (cert, host, port) {
        return true;
      };
    };
  }

  LogOut(bool httpQuest) {
    // if (httpQuest) {
    //   post("api/User/logout", {}, () {}, () {});
    // }
    Navigator.pushAndRemoveUntil(_context!, MaterialPageRoute(builder: (context) => Login()), (route) => route == null);
  }

  //get请求
  get(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack, {bool? showLoading}) async {
    _requstHttp(dio.options.baseUrl + url, successCallBack, showLoading ?? true, 'get', params, errorCallBack);
  }

  //post请求
  post(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack, {bool? showLoading}) async {
    _requstHttp(dio.options.baseUrl + url, successCallBack, showLoading ?? true, "post", params, errorCallBack);
  }

  download(String url, String filePath, void Function(int progress, int total) progressCallBack, Function doneCallBack,
      Function errorCallBack) async {
    dio.options.receiveTimeout = 0;
    try {
      await dio.download(url, filePath, onReceiveProgress: progressCallBack);
      doneCallBack();
    } on DioError catch (e) {
      errorCallBack("400", e.message);
      if (e.response != null) {
        print("Download Error:message:" + e.message);
        print("Download Error:data" + e.response?.data);
        print("Download Error:headers" + e.response!.headers.toString());
      } else {
        print("Download Error:message" + e.message);
      }
    }
  }

  _requstHttp(String url, Function successCallBack, bool showLoading,
      [String? method, Map<String, dynamic>? params, Function? errorCallBack]) async {
    if (showLoading) SmartDialog.show(widget: LoadingWidget(), tag: url, clickBgDismissTemp: false, backDismiss: true);
    Response? response;
    try {
      if (method == 'get') {
        if (params != null && params.length > 0) {
          response = await dio.get(url, queryParameters: params);
        } else {
          response = await dio.get(url);
        }
      } else if (method == 'post') {
        if (params != null && params.length > 0) {
          if (dio.options.headers["Content-Type"] == "application/json")
            response = await dio.post(url, data: json.encode(params));
          else
            response = await dio.post(url, data: FormData.fromMap(params));
        } else {
          response = await dio.post(url);
        }
      }
    } on DioError catch (error) {
      if (showLoading) SmartDialog.dismiss(tag: url);
      // 请求错误处理
      Response errorResponse;
      if (error.response != null) {
        errorResponse = error.response!;
      } else {
        errorResponse = new Response(statusCode: 666, requestOptions: RequestOptions(path: ""));
      }
      // 请求超时
      if (error.type == DioErrorType.connectTimeout) {
        errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
      }
      // 一般服务器错误
      else if (error.type == DioErrorType.receiveTimeout) {
        errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
      }
      print('╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════');
      print('║HttpGo请求url: ' + url);
      print('║HttpGo请求头: ' + dio.options.headers.toString());
      print('║HttpGo请求参数: ' + params.toString());
      print('║HttpGo请求异常statusCode:${errorResponse.statusCode}');
      print('║HttpGo请求异常statusMessage:${errorResponse.statusMessage}');
      print('║HttpGo请求异常errorResponse:${errorResponse.toString()}');
      print('║HttpGo请求异常message: ' + error.message);
      print('╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════');
      _error(errorCallBack, errorResponse.statusCode.toString(), error.message);
      return '';
    } catch (e, stack) {
      if (showLoading) SmartDialog.dismiss(tag: url);
    } finally {
      if (showLoading) SmartDialog.dismiss(tag: url);
    }

    if (showLoading) SmartDialog.dismiss(tag: url);
    if (response != null) {
      print('╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════');
      print('║HttpGo请求url: ' + url);
      print('║HttpGo请求头: ' + dio.options.headers.toString());
      print('║HttpGo请求参数: ' + params.toString());
      print('║HttpGo请求：返回参数: ' + response.toString());
      print('╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════');
    }
    String dataStr = json.encode(response?.data);
    Map<String, dynamic> dataMap = json.decode(dataStr);
    dataMap["errorCode"] = dataMap["errorCode"] ?? "200";
    if (dataMap["errorCode"].toString() != "200") {
      _error(errorCallBack, (dataMap["errorCode"]).toString(), dataMap["message"]);
      // if (response?.data["errorCode"].toString() == "202") {
      //   LogOut(false);
      // }
    } else
      successCallBack(dataMap["data"]);
  }

  _error(Function? errorCallBack, String code, String error) {
    if (errorCallBack != null) {
      errorCallBack(code, error);
    }
  }
}

/*
 * dio网络请求失败的回调错误码
 */
class ResultCode {
  ///正常返回是1
  static const SUCCESS = 1;

  ///异常返回是0
  static const ERROR = 0;

  /// When opening  url timeout, it occurs.
  static const CONNECT_TIMEOUT = -1;

  ///It occurs when receiving timeout.
  static const RECEIVE_TIMEOUT = -2;

  /// When the server response, but with a incorrect status, such as 404, 503...
  static const RESPONSE = -3;

  /// When the request is cancelled, dio will throw a error with this type.
  static const CANCEL = -4;

  /// read the DioError.error if it is not null.
  static const DEFAULT = -5;
}
